home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
- * use is allowed under the terms of the DICE-LICENSE FILE,
- * DICE-LICENSE.TXT.
- */
-
- /*
- * SYM.C
- *
- */
-
- #include "defs.h"
-
- Prototype int hash(ubyte *, short);
- Prototype Sym *FindSymbol(ubyte *, short);
- Prototype int UndefSymbol(ubyte *, short);
- Prototype void DefineOptSymbol(char *);
- Prototype Sym *DefineSimpleSymbol(ubyte *, ubyte *, short);
- Prototype Sym *DefineSymbol(ubyte *, short, short, short, char **, short *, ubyte *, short, short, long);
-
- Prototype void DumpPrecompSymbols(FILE *);
- Prototype void DefinePrecompSymbol(Sym *);
-
- Prototype long SymGroup;
-
- static Sym *SymHash[HSIZE];
- static Sym *SymCache;
-
- long SymGroup;
-
- #ifdef NO_ASM
-
- int
- hash(ubyte *ptr, short len)
- {
- long hv = 0x1234FCD1;
-
- while (len) {
- hv = (hv >> 23) ^ (hv << 5) ^ *ptr;
- ++ptr;
- --len;
- }
- return(hv & HMASK);
- }
-
- #endif
-
- Sym *
- FindSymbol(ubyte *name, short len)
- {
- Sym *sym;
- short hv = hash(name, len);
-
- for (sym = SymHash[hv & HMASK]; sym; sym = sym->Next) {
- if (sym->Hv == hv && sym->SymLen == len && cmpmem(name, sym->SymName, len) == 0) {
- if ((sym->Type & SF_SPECIAL) || (sym->Type & SF_RECURSE) == 0) {
- if (sym->Type & SF_SPECIAL)
- ModifySymbolText(sym, sym->Type);
- break;
- }
- }
- }
- return(sym);
- }
-
- int
- UndefSymbol(ubyte *name, short len)
- {
- Sym **psym;
- Sym *sym;
- short hv = hash(name, len);
-
- for (psym = &SymHash[hv & HMASK]; (sym = *psym) != NULL; psym = &sym->Next) {
- if (sym->Hv == hv && sym->SymLen == len && cmpmem(name, sym->SymName, len) == 0)
- break;
- }
- if (sym == NULL)
- return(0);
- *psym = sym->Next;
- sym->Next = SymCache;
- SymCache = sym;
- return(1);
- }
-
- /*
- * handle single level define
- */
-
- void
- DefineOptSymbol(str)
- char *str;
- {
- char *ptr;
-
- for (ptr = str; *ptr && *ptr != '='; ++ptr);
- if (*ptr == '=') {
- *ptr = ' ';
- ++ptr;
- ptr += strlen(ptr);
- }
- do_define(str, ptr - str, NULL);
- #ifdef NOTDEF
- DefineSimpleSymbol(str, ptr, 0);
- #endif
- }
-
- Sym *
- DefineSimpleSymbol(ubyte *symName, ubyte *symText, short symType)
- {
- return(DefineSymbol(symName, strlen(symName), symType, -1, NULL, NULL, symText, 0, 0, strlen(symText)));
- }
-
- Sym *
- DefineSymbol(
- ubyte *name,
- short len,
- short type,
- short numArgs,
- char **args,
- short *lens,
- ubyte *text,
- short allocName,
- short allocText,
- long textSize
- ) {
- short hv = hash(name, len);
- Sym **psym = &SymHash[hv & HMASK];
- Sym *sym;
-
- if ((sym = SymCache) != NULL) {
- SymCache = sym->Next; /* note, fields not zerod */
- } else {
- sym = zalloc(sizeof(Sym));
- }
- sym->Next = *psym;
- *psym = sym;
-
- if (allocName)
- name = AllocCopy(name, len);
- sym->SymName = name;
- sym->SymLen = len;
- sym->Type = type;
- sym->NumArgs = numArgs;
- sym->Hv = hv;
-
- if (numArgs > 0) {
- short i;
-
- sym->Args = AllocCopy(args, numArgs * sizeof(char *));
- sym->ArgsLen = AllocCopy(lens, numArgs * sizeof(short));
- for (i = 0; i < numArgs; ++i)
- sym->Args[i] = AllocCopy(args[i], lens[i]);
- } else {
- sym->Args = NULL;
- sym->ArgsLen = NULL;
- }
- if (allocText)
- text = AllocCopy(text, textSize);
- sym->Text = text;
- sym->TextLen = textSize;
- sym->SymGroup = SymGroup;
-
- return(sym);
- }
-
- /*
- * Precompiled header file routines
- */
-
- void
- DefinePrecompSymbol(sym)
- Sym *sym;
- {
- Sym **psym;
-
- /*
- * adjust pointers
- */
-
- sym->SymName = (long)sym->SymName + (char *)sym;
- if (sym->Args) {
- int i;
-
- sym->Args = (ubyte **)((long)sym->Args + (char *)sym);
- sym->ArgsLen = (short *)((long)sym->ArgsLen + (char *)sym);
- for (i = 0; i < sym->NumArgs; ++i) {
- sym->Args[i] = (long)sym->Args[i] + (char *)sym;
- }
- }
- if (sym->Text)
- sym->Text = (long)sym->Text + (char *)sym;
-
- /*
- * enter into hash table
- */
-
- psym = &SymHash[sym->Hv & HMASK];
- sym->Next = *psym;
- *psym = sym;
- }
-
- /*
- * dump symbols in current SymGroup
- */
-
- void
- DumpPrecompSymbols(fo)
- FILE *fo;
- {
- long i;
- Sym **psym;
-
- for (i = 0, psym = SymHash; i < HSIZE; ++i, ++psym) {
- Sym *sym;
-
- for (sym = *psym; sym; sym = sym->Next) {
- if (sym->SymGroup == SymGroup) {
- long bytes = sizeof(Sym);
- Sym xsym = *sym;
-
- /*
- * dump symbol
- */
-
- xsym.SymName = (char *)bytes;
- bytes += sym->SymLen;
-
- xsym.Text = (char *)bytes;
- bytes += sym->TextLen;
-
- bytes = (bytes + 3) & ~3; /* LW-ALIGN */
-
- if (sym->Args) {
- int i;
-
- xsym.Args = (ubyte **)bytes;
- bytes += sym->NumArgs * sizeof(char *);
-
- xsym.ArgsLen = (short *)bytes;
- bytes += sym->NumArgs * sizeof(sym->ArgsLen[0]);
-
- for (i = 0; i < sym->NumArgs; ++i)
- bytes += sym->ArgsLen[i];
- }
-
- bytes = (bytes + 3) & ~3; /* LW-ALIGN */
-
- fwrite(&bytes, sizeof(long), 1, fo);
-
- bytes = sizeof(Sym) + sym->SymLen + sym->TextLen;
- fwrite(&xsym, sizeof(Sym), 1, fo);
- fwrite(sym->SymName, sym->SymLen, 1, fo);
- fwrite(sym->Text, sym->TextLen, 1, fo);
-
- while (bytes & 3) {
- putc(0, fo);
- ++bytes;
- }
-
- if (sym->Args) {
- int i;
-
- bytes += sym->NumArgs * sizeof(char *);
- bytes += sym->NumArgs * sizeof(sym->ArgsLen[0]);
-
- for (i = 0; i < sym->NumArgs; ++i) {
- fwrite(&bytes, sizeof(long), 1, fo);
- bytes += sym->ArgsLen[i];
- }
- fwrite(sym->ArgsLen, sizeof(*sym->ArgsLen), sym->NumArgs, fo);
-
- /*
- * write argument text
- */
-
- for (i = 0; i < sym->NumArgs; ++i)
- fwrite(sym->Args[i], 1, sym->ArgsLen[i], fo);
- }
-
- while (bytes & 3) {
- putc(0, fo);
- ++bytes;
- }
-
- fwrite(&bytes, sizeof(long), 1, fo);
- }
- }
- }
- }
-
-